iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0

昨天文章最後留了一個問題「當一段長文字送進分詞器時,底層怎麼決定在哪裡切一刀當作一個 Token 的,哪裡該合併?」今天我們來把 Token 出航前的最後半哩路走完吧,來看看它是怎麼轉成模型看得懂的向量,進到模型的世界裡。


1. 當一句新的話送進分詞器,BPE 怎麼決定在哪切一刀?

在推論階段,BPE 會沿用訓練時學到的合併規則與優先順序。其中一種高效率的實作方式,就是透過優先佇列(Priority Queue / Max Heap)管理目前可以合併的相鄰碎片:

  1. 先通通打碎:輸入 "lowest",先拆成最小字元 ['l', 'o', 'w', 'e', 's', 't']
  2. 檢查相鄰的 Pair:看每對相鄰碎片黏起來後「字典裡有沒有收錄」。有的話,就查出它的分數丟進 Max-Heap 裡排隊(分數越高排越前面)。
    • 比如 e + s -> es(字典有收,丟進 Heap)
    • 比如 o + w -> ow(字典沒收,直接忽略)
  3. 迴圈合併,直到 Heap 空了為止
    • 拿最高分:從 Heap 拿出當前分數最高的一對合併(例如 es 黏成 es)。
    • 更新相鄰鄰居:字串變成 ['l', 'o', 'w', 'es', 't'],這時檢查新產生的左右鄰居(如 es + t -> est),字典有收就再丟進 Heap。
    • 重複動作:依序再黏成 est、黏成 lo、黏成 low
    • 停在哪裡? 當字串只剩 ['low', 'est'],兩者合體的 lowest 在字典裡查不到,Heap 沒有其他候選人可拿時,迴圈立刻停止!

最後輸出切分結果:['low', 'est']

碎片切好後,查字典對應編號:low1042est8007,字串就此轉換成一串整數陣列:[1042, 8007]

此時,分詞器的工作正式結束,接下來交棒給神經網路來處理。

💡 題外話:為什麼神經網路不能直接拿整數計算?
Token ID 只是個「代號」,沒有連續數值的意義。如果直接丟進神經網路算矩陣乘法,模型會誤以為編號 200 的「香蕉」是編號 100 的「蘋果」兩倍大。所以,代號還需要再換一次裝。


2. 從 Token 到 Embedding 其實就只是「查表」

為了避免模型依賴 Token ID 的順序性來進行訓練,所以額外建立了一個 Embedding Matrix 來表示字典裡的 Tokens,當中每一列代表字典裡一種 Token 的特徵向量,所以這張表的大小通常會是 [字典大小, 隱藏層維度](例如 [32000, 4096],表示字典大小有 32000 種 Token,每種 Token 都以一個 4096 維的向量表示)。而所謂的 Embedding Lookup,底層其實就是單純的陣列索引(Array Indexing):

token_id = 1042
token_vector = embedding_matrix[token_id]

拿出來的這條向量,才是模型真正用來理解語意的單位。當中可以特別注意,這個 Embedding Matrix 在模型訓練的階段,是會被一起訓練的。一開始裡面的數值通常是隨機填入的小浮點數,隨著訓練迭代,裡面的數值會跟著反向傳播(Backpropagation)進行更新。訓練結束後,在 4,096 維的空間裡,意思相近的詞(如「蘋果」與「香蕉」)距離較容易會比較近。也就是因為這樣,模型得以在幾何空間中重新建立每種 Token 之間的關係,進而與原本離散的 Token ID 解耦(Decouple)。


3. 為什麼換了 Tokenizer,模型就無法運作了?

回答一個常見疑問:「如果覺得某個開源模型的 Tokenizer 切中文不好用,能自己換一個給它嗎?」答案是:不是不行,但不能在保留原模型權重,又不做配套調整的情況下,任意換用不相容的 Tokenizer。

因為在訓練階段中,模型使用的這套字典裡,假設第 1042 列向量已經被調整為代表「蘋果」,第 8007 列固定代表「飛機」, Embedding Matrix 也是透過這本字典來學習的,所以整張矩陣跟那本字典是嚴格一對一綁定的。除非能在確保原本 Token 跟 Embedding 關係沒變的情況下更新 Tokenizer,否則,如果換了新 Tokenizer,字典裡變成「飛機」的編號是 1042,那就會發生:

  • 輸入「飛機」,分詞器輸出 ID 1042
  • 模型查第 1042 列,拿到的卻是「蘋果」的特徵。
  • 模型可能產生語意錯亂或品質大幅下降的輸出,若新 ID 超出原本詞表範圍,也可能直接發生索引錯誤。

這就是為什麼 Tokenizer 與模型權重無法拆分。只要字典變動或是直接更換字典,模型就會拿到錯誤的 Embedding,就可能對不上原本的語意了。這也是為什麼開源模型釋出時,一定會附帶 tokenizer.model 或分詞配置檔案。


下一篇,我們要正式踏入 LLM 內部,看看模型是怎麼透過這些 Embedding 向量預測下一個 Token 的。明天見~


參考資料


上一篇
Day 04 | 少年 Token(中):SentencePiece 說文解字
下一篇
Day 06 | 少年 Token(番外):那 Unigram 呢?
系列文
在贏家書寫歷史之前:我所看見的 AI,與一位工程師共舞著10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言